package com.changgou.oauth.service.impl;

import com.changgou.oauth.service.AuthService;
import com.changgou.oauth.util.AuthToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Base64;
import java.util.Map;

/*****
 * @Author: 黑马训练营
 * @Description: com.changgou.oauth.service.impl
 ****/
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private RestTemplate restTemplate;

    //可以获取指定服务的IP端口
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    /***
     * 登录
     * @param grantType ：授权类型
     * @param username ： 用户名
     * @param password ： 密码
     * @param clientId ： 客户端ID
     * @param secret ：   秘钥
     */
    @Override
    public AuthToken login(String grantType, String username, String password, String clientId, String secret) {
        //获取指定服务的实例信息
        ServiceInstance serviceInstance = loadBalancerClient.choose("user-auth");

        //获取服务的路径
        String url = serviceInstance.getUri().toString()+"/oauth/token";

        //登录的地址
        //String url = "http://localhost:9001/oauth/token";

        //封装一个对象，用于存储提交的请求体
        MultiValueMap<String, String> bodys = new LinkedMultiValueMap<String, String>();
        bodys.add("grant_type",grantType);
        bodys.add("username",username);
        bodys.add("password",password);

        //封装一个对象用于存储请求头
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        headers.add("Authorization",base64(clientId,secret));

        //封装一个对象， 用于存储提交数据的请求体和请求头
        HttpEntity httpEntity = new HttpEntity(bodys,headers);

        /***
         * 执行登录，获取登录后的结果数据
         * 1:提交的请求地址
         * 2:提交方法
         * 3:请求头或者请求体
         * 4:响应的数据需要转换的类型
         */
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Map.class);
        Map<String,String> body = response.getBody();

        //令牌封装AuthToken
        AuthToken authToken = new AuthToken();
        authToken.setAccessToken(body.get("access_token"));
        authToken.setRefreshToken(body.get("refresh_token"));
        authToken.setJti(body.get("jti"));

        return authToken;
    }

    /***
     * 将请求头中clientid、secret拼接并且使用Base64编码
     * @param clientid
     * @param secret
     * @return
     */
    public String base64(String clientid,String secret){
        String str = "Basic "+new String(Base64.getEncoder().encode((clientid+":"+secret).getBytes()));
        return str;
    }
}
